<?php


namespace backend\modules\tool\Job;


use backend\modules\tool\DataSource\Log\Log;
use backend\modules\tool\DataSource\Script;
use backend\modules\tool\DataSource\SqlSource;
use backend\modules\tool\DataSource\Task\command\CommandFaced;
use backend\modules\tool\helpers\Context;
use backend\modules\tool\models\DataSourceTask;
use backend\modules\tool\models\Node;
use backend\modules\tool\models\SqlConfig;
use SebastianBergmann\CodeCoverage\Report\PHP;
use yii\db\Exception;

class SqlNode extends SqlSource
{
    protected $id;
    protected $batch_num=130;
    protected $run_fun="";
    protected $fun_name;
    protected $node;
    protected $log;
    public function __construct($id)
    {
        $this->id=$id;
        $task=DataSourceTask::find()->where(["id"=>$id])->one();
        $node=Node::find()->where(["id"=>$task->task_id])->one();
        $this->log=Log::SingleTon($id);
        $this->target_pdo=SqlConfig::GetConfigPdo($node->source_config);
        $this->primary_key_conflict=$node->way;
        $this->log->write("主键冲突处理方式===>{$node->way}");
        $this->target_pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
        Context::SingleTon()->setSourcePdo($this->target_pdo);
        $this->local_pdo=SqlConfig::GetConfigPdo($node->desc_config);
        Context::SingleTon()->setDescPdo($this->local_pdo);
        Context::SingleTon()->setNode($node);
        if(!empty($node->batch_size)){
            $this->batch_num=$node->batch_size;

        }
        $this->log->write("批量处理数量===>".$this->batch_num);

        $this->is_bind=$node->is_bind;
        if($this->is_bind){
            $this->log->write("插入数据方式===>使用参数绑定");
        }else{
            $this->log->write("插入数据方式===>原生插入");
        }
        $this->node=$node;
        if(!empty($node->before_sql)){
            foreach (explode("--****--",$node->before_sql) as $item){
                if(!empty($item)){
                    $this->local_pdo->exec($item);
                }
            }
        }

        $this->run_fun=$node->run_fun;
        if(!empty($node->run_fun)){
            try {
//                $this->run_fun=str_replace("<?php","",$this->run_fun);
                preg_match_all("/function (.*?)\(/is", $node->run_fun, $matchs);
                $this->fun_name = $matchs[1][0];
                if(empty($this->fun_name)){
                    throw new \Exception("fun name reqiured but {$this->fun_name} given!");
                }
                new Script($node->run_fun);
            }
            catch (\Exception $exception){
                echo "failed parse fun .$exception";
                $this->log->write($exception);
                if(CommandFaced::getDirver()::getRunVersion()=="Windows") {
                    sleep(10);
                }
            }

        }
        $this->sql=$node->sql_string;
        if(preg_match('/<\?php/u',$this->sql)){
            try {
                $this->sql=str_replace('<?php',"",$this->sql);
                preg_match_all("/function (.*?)\(/is", $this->sql, $matchs);
                $fun = $matchs[1][0];
                if(empty($fun)){
                    throw new \Exception("fun name reqiured but {$this->fun_name} given!");
                }
                new Script($this->sql);
                $this->sql=$fun();
                if(empty($this->sql)){
                    throw new \Exception("fun must return a sql string");
                }
                if(is_string($this->sql)) {
                    $this->log->write("动态生成sql===>" . $this->sql);
                }else{
                    $this->log->write("动态生成sql===>" . json_encode($this->sql));
                }
            }
            catch (\Exception $exception){
                echo "failed parse fun .$exception";
                $this->log->write($exception);
                if(CommandFaced::getDirver()::getRunVersion()=="Windows") {
                    sleep(10);
                }
                throw new \Exception($exception);
            }
        }

        $this->table_name=$node->desc_table;

        parent::__construct($id);
    }
    public function StoreData($data)
    {
        Context::SingleTon()->set("hanndle_num",Context::SingleTon()->get("hanndle_num")+count($data));
        if (!empty($this->fun_name)) {
            $fun = $this->fun_name;
            $data = $fun($data);
        }
        if (CommandFaced::getDirver()::getRunVersion() == "Windows") {
            echo "TaskName" . $this->node->node_name . PHP_EOL;
            echo microtime(true) - start_at . PHP_EOL;
        }
        parent::StoreData($data); // TODO: Change the autogenerated stub
    }
    public function afterRun()
    {
        parent::afterRun(); // TODO: Change the autogenerated stu
    }
}